home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / JMaskedTextField.java < prev    next >
Text File  |  1998-10-19  |  11KB  |  324 lines

  1. package com.symantec.itools.swing;
  2.  
  3. import java.awt.event.KeyEvent;
  4. import java.awt.event.KeyAdapter;
  5. import java.awt.event.FocusEvent;
  6. import java.awt.event.FocusAdapter;
  7. import java.awt.datatransfer.*;
  8. import com.sun.java.swing.text.Document;
  9. import com.sun.java.swing.text.PlainDocument;
  10. import com.sun.java.swing.event.DocumentListener;
  11. import com.sun.java.swing.event.DocumentEvent;
  12.  
  13. public class JMaskedTextField extends com.sun.java.swing.JTextField {
  14.  
  15.   /* These constants are used to specify the data type information needed
  16.      to specialize input time behavior based on data type.
  17.      For now, the only such difference is between text and numeric:
  18.      In numeric fields, an empty field is initialzed to zero, and input of
  19.      a decimal point when the mask contains one and the cartet is to its left
  20.      causes the caret to move to the right of the decimal point position.
  21.   */
  22.   public static final int texttype = MaskEngine.texttype;
  23.   public static final int numbtype = MaskEngine.numbtype;
  24.   public static final int datetype = MaskEngine.datetype;
  25.   public static final int timetype = MaskEngine.timetype;
  26.  
  27.   // ctors
  28.     public JMaskedTextField (                   ) { this(""         , 0              ); }
  29.     public JMaskedTextField (int numberOfColumns) { this(""         , numberOfColumns); }
  30.     public JMaskedTextField (String initialText ) { this(initialText, 256            ); }
  31.     public JMaskedTextField (String initialText, int numberOfColumns)    {
  32.       this(null, initialText, numberOfColumns);
  33.     }
  34.  
  35.     // All other constructors call this one
  36.   public JMaskedTextField(Document doc, String initialText, int numberOfColumns) {
  37.     super(doc, initialText, numberOfColumns);
  38.   }
  39.  
  40.   /**
  41.     Initialize the field
  42.   */
  43.   public synchronized void setMaskedText(String t) {
  44.     if(getMask().equals("")){
  45.         setText(t);
  46.     }else{
  47.         StringBuffer newData = new StringBuffer();
  48.         _firstInputPos = _maskEngine.initDisplay(t, newData);
  49.         setText(newData.toString());
  50.         if (_haveFocus && isEditable())
  51.         select(_firstInputPos, _firstInputPos + 1);
  52.     }
  53.   }
  54.  
  55.   // Returns current text with mask characters removed
  56.   public synchronized String getUnmaskedText() {
  57.     if(getMask().equals(""))
  58.         return getText();
  59.     StringBuffer newData = new StringBuffer();
  60.     _dataComplete = _maskEngine.stripMask(getText(), newData);
  61.     return newData.toString();
  62.   }
  63.  
  64.   /**
  65.    * This is a standard AWT method which gets called when
  66.    * this component is added to a container.
  67.    *
  68.    * @see #removeNotify
  69.    */
  70.   public synchronized void addNotify() {
  71.     if (_focusListener == null) {
  72.     _focusListener = new FocusAdapter() {
  73.                         public void focusGained(FocusEvent e) { gotFocus (e); }
  74.                         public void focusLost  (FocusEvent e) { lostFocus(e); }
  75.                     };
  76.     addFocusListener(_focusListener);
  77.     }
  78.     super.addNotify();
  79.   }
  80.  
  81.   /**
  82.    * This method gets called when this component is removed from a
  83.    * container.
  84.    *
  85.    * @see #addNotify
  86.    */
  87.   public synchronized void removeNotify() {
  88.     if (_focusListener != null) {
  89.         removeFocusListener(_focusListener);
  90.         _focusListener = null;
  91.     }
  92.     super.removeNotify();
  93.   }
  94.  
  95.   public synchronized void cut(Clipboard clipboard) {
  96.     if (!isEditable())
  97.       return;
  98.     _activity = true;
  99.     StringBuffer newData = new StringBuffer();
  100.     int selStart = getSelectionStart();
  101.     String clipboardData = _maskEngine.cut(getText(), selStart,
  102.                                            getSelectionEnd(),
  103.                                            newData);
  104.     StringSelection ss = new StringSelection(clipboardData);
  105.     clipboard.setContents(ss, ss);
  106.     setText(newData.toString());
  107.     setCaretPosition(selStart);
  108.   }
  109.  
  110.   public synchronized void paste(Clipboard clipboard) {
  111.     if (!isEditable())
  112.       return;
  113.     _activity = true;
  114.     StringBuffer newData = new StringBuffer();
  115.     String data = "";
  116.     try {
  117.       data = (String)clipboard.getContents(this).getTransferData(DataFlavor.stringFlavor);
  118.     } catch (Exception e) {}
  119.     int pos = getCaretPosition();
  120.     int selStart = getSelectionStart();
  121.     int selEnd = getSelectionEnd();
  122.     int newpos = _maskEngine.paste(getText(), data, pos, newData,
  123.                                    selStart, selEnd);
  124.     if (newpos < 0)   // beep if paste failed
  125.       getToolkit().beep();
  126.     if (newpos == -2) // quit if filter mismatch
  127.       return;
  128.     setText(newData.toString());
  129.     if (newpos >= 0) {              // if good new caret position
  130.       select(newpos, newpos + 1);  // select this position
  131.     } else {
  132.       select(0, 0);  // turn off selection
  133.       if (newpos != -1)  // cursor just moved out of range
  134.         setCaretPosition(newpos + 1000);  // move one past last filter
  135.     }
  136.   }
  137.  
  138.   // Override of JTextComponent
  139.   public void cut() {
  140.     //vasu start
  141.     if(getMask().equals("")){
  142.         super.cut();
  143.     }else{
  144.     //vasu end
  145.         cut(java.awt.Toolkit.getDefaultToolkit().getSystemClipboard());
  146.     }
  147.   }
  148.  
  149.   // Override of JTextComponent
  150.   public void paste() {
  151.     //vasu start
  152.     if(getMask().equals("")) {
  153.         super.paste();
  154.     }else{
  155.     //vasu end
  156.         paste(java.awt.Toolkit.getDefaultToolkit().getSystemClipboard());
  157.     }
  158.   }
  159.  
  160.   public void   setMask    (String mask) {        _maskEngine.setMask    (mask); }
  161.   public String getMask    (           ) { return _maskEngine.getMask    (    ); }
  162.   public void   setDatatype(int    type) {        _maskEngine.setDatatype(type); }
  163.   public int    getDatatype(           ) { return _maskEngine.getDatatype(    ); }
  164.  
  165.   public boolean isDataComplete() {
  166.     //vasu start
  167.     if(getMask().equals("")) return true;
  168.     //vasu end
  169.     if (!_dataComplete) {
  170.       if (!_activity)
  171.         return true;
  172.       _dataComplete = _maskEngine.stripMask(getText(), new StringBuffer());
  173.     }
  174.     return _dataComplete;
  175.   }
  176.  
  177.   protected void gotFocus(FocusEvent e) {
  178.     _activity = false;
  179.     _haveFocus = true;
  180.     if (getText().length() == 0)
  181.       setMaskedText("");  // show the mask literals if field is empty
  182.     else if (isEditable() && !getMask().equals(""))//vasu
  183.       select(_firstInputPos, _firstInputPos + 1);
  184.   }
  185.  
  186.   protected void lostFocus(FocusEvent e) {
  187.     //select(0, 0);//vasu
  188.     _haveFocus = false;
  189.     if (isEditable() && _activity) {
  190.       try {
  191.         _docListenerDisabled = true;
  192.         _document.remove(0, _document.getLength());
  193.         _document.insertString(0, getUnmaskedText(), null);
  194.       } catch (com.sun.java.swing.text.BadLocationException ex) {
  195.         badLocException();
  196.       } finally {
  197.         _docListenerDisabled = false;
  198.       }
  199.     }
  200.   }
  201.  
  202.   // Override JTextComponent
  203.   protected void processComponentKeyEvent(KeyEvent e) {
  204.     //vasu start - because we check whether or not something
  205.     //             was done before we update the model
  206.     _activity = true;
  207.     //vasu end
  208.  
  209.     switch(e.getID()) {
  210.     case KeyEvent.KEY_TYPED:
  211.       if (_maskEngine.isHandledKey(e) && isEditable())
  212.         processKey(e);
  213.       else
  214.         super.processComponentKeyEvent(e);
  215.       break;
  216.     case KeyEvent.KEY_PRESSED:
  217.       if (_maskEngine.isHandledKey(e) && isEditable()) {
  218.         e.consume();
  219.         if (_keyPressed) { // key must be auto-repeating
  220.           if (Character.isISOControl(e.getKeyChar()))
  221.             processKey(e);
  222.         } else
  223.           _keyPressed = true;
  224.       } else
  225.         super.processComponentKeyEvent(e);
  226.       break;
  227.     case KeyEvent.KEY_RELEASED:
  228.       _keyPressed = false;
  229.       if (_maskEngine.isHandledKey(e) && isEditable()) {
  230.         if (Character.isISOControl(e.getKeyChar()))
  231.           processKey(e);
  232.       } else
  233.         super.processComponentKeyEvent(e);
  234.       break;
  235.     }
  236.   }
  237.  
  238.   protected void processKey(KeyEvent e) {
  239.     _activity = true;
  240.     e.consume();
  241.     int pos = getSelectionStart();
  242.     StringBuffer newData = new StringBuffer("");
  243.     String data = getText();
  244.     int newpos = _maskEngine.processKey(e, pos, data, newData,
  245.                                         pos, getSelectionEnd());
  246.     if (newpos == -2)  // quit if filter mismatch
  247.       return;
  248.     setText(newData.toString());
  249.     if (newpos >= 0) {              // if good new caret position
  250.       select(newpos, newpos + 1);  // select this position
  251.     } else if (newpos == -1) {
  252.       getToolkit().beep();
  253.       select(0, 0);
  254.     } else {  // cursor just moved out of range
  255.       select(0, 0);  // turn off selection
  256.       setCaretPosition(newpos + 1000);  // move one past last filter
  257.     }
  258.   }
  259.  
  260.   // Override
  261.   // This gets called during superclass construction!
  262.   public void setDocument(Document d) {
  263.     if (_docListener == null)
  264.     _docListener = new DocumentListener() {
  265.         public void changedUpdate(DocumentEvent e) { docChange(e); }
  266.         public void removeUpdate (DocumentEvent e) { docRemove(e); }
  267.         public void insertUpdate (DocumentEvent e) { docInsert(e); }
  268.     };
  269.  
  270.     if (_document != null)
  271.     _document.removeDocumentListener(_docListener);
  272.     _document = d;
  273.     _document.addDocumentListener(_docListener);
  274.     if (_myDoc == null)
  275.     _myDoc = new PlainDocument();
  276.     super.setDocument(_myDoc);
  277.   }
  278.  
  279.   // These shouldn't get called
  280.   protected void docChange(DocumentEvent e) {
  281.     if (_docListenerDisabled)
  282.       return;
  283. //    System.out.println("Masked Doc Listener Change Called");
  284.   }
  285.  
  286.   protected void docRemove(DocumentEvent e) {
  287.     if (_docListenerDisabled)
  288.       return;
  289.   //  System.out.println("Masked Remove Called");
  290.     setText("");
  291.   }
  292.  
  293.   // This gets called on data insertion into the field
  294.   protected void docInsert(DocumentEvent e) {
  295.     if (_docListenerDisabled)
  296.       return;
  297.     int len = e.getLength();
  298.     String data = "";
  299.     try {
  300.       data = _document.getText(0, len);
  301.     } catch(com.sun.java.swing.text.BadLocationException ex) {
  302.       badLocException();
  303.     }
  304.     setMaskedText(data);
  305.   }
  306.  
  307.   protected void badLocException() {
  308.     getToolkit().beep();
  309.     System.out.println("Bad Location Exception in JMaskedTextField");
  310.   }
  311.  
  312.   private PlainDocument    _myDoc         = null;
  313.   private DocumentListener _docListener   = null;
  314.   private Document         _document      = null;
  315.   private boolean          _docListenerDisabled = false;
  316.   private boolean          _dataComplete  = true;    // true iff no mandatory filters are empty
  317.   private boolean          _haveFocus     = false;   // true if this component has input focus
  318.     private boolean          _keyPressed    = false;   // true if a key is down
  319.     private boolean          _activity      = false;
  320.   private int              _firstInputPos = 0;       // position of first filter
  321.   private MaskEngine       _maskEngine    = new MaskEngine();
  322.   private FocusAdapter     _focusListener = null;
  323. }
  324.